package cn.iocoder.yudao.module.call.framework.client.impl.dfc;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.*;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.call.api.client.dto.*;
import cn.iocoder.yudao.module.call.framework.client.impl.AbstractCallClient;
import cn.iocoder.yudao.module.call.framework.client.property.CallProperties;
import cn.iocoder.yudao.module.call.enums.CallResultTypeEnum;
import cn.iocoder.yudao.module.call.utils.TimeUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 数字云双向回拨
 */
@Slf4j
public class DFCClient extends AbstractCallClient {

    final static String url = "http://agent.duofangtongxin.com/open";

    final static String CALL_API = "/api-call/bind";
    final static String HANGUP_API = "/api-call/unbind";

    // 主叫加白接口
    final static String WHITE_API = "/api-number-white/white";

    final static String ERROR_MSG = "未接通";

    @Override
    protected void doInit() {

    }

    public DFCClient(CallProperties properties) {
        super(properties);
        // check config properties not null
        Assert.notNull(properties.getAppKey(), "AccessKey 不能为空");
        Assert.notNull(properties.getAppSecret(), "AppSecret 不能为空");
        Assert.notNull(properties.getNotifyUrl(), "话单推送地址不能为空");
    }

    @Override
    public CallRespDTO handleCall(CallReqDTO callReqDTO) {

        // TODO: 数字云这里， 虚拟号需要从租户审批业务中查找
        // TODO: prod 环境下可能telX使用共享号码池， 可不传
        Map<String, Object> body = new HashMap<String, Object>() {{
            put("accessKey", properties.getAppKey());
            put("telA", callReqDTO.getTelephone());
            put("telB", callReqDTO.getCallee());
            put("expire", 60);
            put("telX", "08982222609");
            put("notifyUrl", properties.getNotifyUrl());
        }};
        body.put("sign", sign(body));
        log.info("handleCall ----- req body --- {}", JSONUtil.toJsonStr(body));
        HttpRequest httpRequest = HttpUtil.createPost(StrUtil.concat(true, url, CALL_API));
        httpRequest.body(JSONUtil.toJsonStr(body));
        HttpResponse httpResponse = httpRequest.execute();
        CallRespDTO callRespDTO = CallRespDTO.ofError();
        if (httpResponse.isOk()) {
            JSONObject jsonObject = JSONUtil.parseObj(httpResponse.body());
            log.info("handleCall ----- resp body --- {}", httpResponse.body());

            if (ObjectUtil.equals(jsonObject.get("code"),"0000")) {
                JSONObject data = jsonObject.getJSONObject("data");
                callRespDTO.setSuccess(true);
                callRespDTO.setReqNo(data.getStr("bindId"));
            } else {
                callRespDTO.setMessage(String.format("Channel (%s) %s", properties.getName(), jsonObject.getStr("message")));
            }
        } else {
            callRespDTO.setMessage(String.format("Channel (%s) %s", properties.getName(), "HTTP请求失败"));
        }

        return callRespDTO;
    }

    private String sign(Map<String, Object> map) {
        StringBuilder sb = new StringBuilder(properties.getAppSecret());
        for (Map.Entry entry : MapUtil.sort(map).entrySet()) {
            if (ObjectUtil.isNotEmpty(entry.getValue())) {
                sb.append(entry.getKey()).append(entry.getValue());
            }
        }
        return SecureUtil.md5(sb.toString()).toUpperCase();
    }

    @Override
    public AgentRespDTO handleAgent(AgentReqDTO agentReqDTO) {
        return null;
    }



    @Override
    public CallNotifyDTO handleNotify(JSONObject jsonObject) {
        log.info("handleNotify: ------ {}", jsonObject);
        CallNotifyDTO callNotifyDTO = new CallNotifyDTO();
        callNotifyDTO.setReqNo(jsonObject.getStr("bindId"));
        Integer seconds = jsonObject.getInt("duration");
        Integer callStatus = jsonObject.getInt("callStatus");
        // 录音下载地址
        // 获取话单预生成录音地址
        callNotifyDTO.setTempRecordUrl(jsonObject.getStr("preRecordUrl"));
        callNotifyDTO.setCallSecond(seconds);
        callNotifyDTO.setCallMinute(TimeUtil.secondToMin(seconds));
        if (ObjectUtil.equals(callStatus, 1)) {
            callNotifyDTO.setResultCode("success");
            callNotifyDTO.setResultType(CallResultTypeEnum.SUCCESS.getValue());
            callNotifyDTO.setResultMsg(CallResultTypeEnum.SUCCESS.getMsg());
        } else {
            callNotifyDTO.setResultCode("fail");
            callNotifyDTO.setResultType(CallResultTypeEnum.FAIL.getValue());
            callNotifyDTO.setResultMsg(CallResultTypeEnum.FAIL.getMsg());
        }
        // 呼叫时间的计算
        callNotifyDTO.setStartTime(LocalDateTimeUtil.parse(jsonObject.getStr("startTime"), DatePattern.NORM_DATETIME_FORMATTER));
        callNotifyDTO.setEndTime(LocalDateTimeUtil.parse(jsonObject.getStr("endTime"), DatePattern.NORM_DATETIME_FORMATTER));
//        callNotifyDTO.setUserData(jsonObject.getStr("orderid"));
        return callNotifyDTO;
    }

    @Override
    public boolean createAgent(AgentReqDTO agentReqDTO) {

        // 主叫加白去
        // TODO: 主叫加白需要提供身份证、姓名、中间号， 这三个需要重新搞一下
        return true;

    }

//    @Override
//    public WhiteRespDTO addWhite(WhiteReqDTO reqDTO) {
////        return WhiteRespDTO.ofSuccess(reqDTO.getNumber());
//        Map<String, Object> body = new HashMap<String, Object>() {{
//            put("accessKey", properties.getAppKey());
//            put("telA", reqDTO.getNumber());
//            put("idCard", reqDTO.getIdNumber());
//            put("telX",reqDTO.getTelX());
//            put("name", reqDTO.getRealName());
//        }};
//        if (StrUtil.isNotEmpty(reqDTO.getCode())) {
//            body.put("code", reqDTO.getCode());
//        }
//        body.put("sign", sign(body));
//        log.info("handleWhite ----- req body --- {}", JSONUtil.toJsonStr(body));
//        HttpRequest httpRequest = HttpUtil.createPost(StrUtil.concat(true, url, WHITE_API));
//        httpRequest.body(JSONUtil.toJsonStr(body));
//        HttpResponse httpResponse = httpRequest.execute();
//
//        if (httpResponse.isOk()) {
//            JSONObject jsonObject = JSONUtil.parseObj(httpResponse.body());
//            log.info("handleWhite ----- resp body --- {}", httpResponse.body());
//            if (ObjectUtil.equals(jsonObject.get("code"),"0000")) {
//                JSONObject data = jsonObject.getJSONObject("data");
//                Integer status = data.getInt("status");
//                if (status == 0) {
//                    return WhiteRespDTO.ofWaiting(reqDTO.getNumber());
//                } else if (status == 1) {
//                    return WhiteRespDTO.ofSuccess(reqDTO.getNumber());
//                } else if (status == 2) {
//                    return WhiteRespDTO.ofFail(reqDTO.getNumber(), jsonObject.getStr("message"));
//                }
//            } else {
//                return WhiteRespDTO.ofFail(reqDTO.getNumber(), jsonObject.getStr("message"));
//            }
//        } else {
//            return WhiteRespDTO.ofFail(reqDTO.getNumber(), "API请求失败");
//        }
//        return WhiteRespDTO.ofDefault(reqDTO.getNumber());
//    }

    @Override
    public JSONObject getAccountInfo(String agent) {
        return null;
    }
}
